package com.tanhua.dubbo.api;

import com.tanhua.domain.mongo.*;
import com.tanhua.domain.vo.PublishVO;
import com.tanhua.dubbo.util.IdGenerator;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import com.tanhua.domain.vo.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.List;

@Service
public class PublishApiImpl implements PublishApi {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IdGenerator idGenerator;

    @Override
    public PageResult findRecommendList(Long userId, int page, int pagesize) {
        //1. 查询推荐的动态列表
        Query query = new Query();
        Criteria criteria = Criteria.where("userId").is(userId);
        query.addCriteria(criteria);
        query.with(PageRequest.of(page - 1, pagesize));
        query.with(Sort.by(Sort.Order.desc("created")));

        List<RecommendQuanZi> list = mongoTemplate.find(query, RecommendQuanZi.class);

        long count = mongoTemplate.count(query, RecommendQuanZi.class);

        //2. 转换成Publish列表
        List<Publish> publishList = new ArrayList<>();
        for (RecommendQuanZi quanZi : list) {
            Publish publish = mongoTemplate.findById(quanZi.getPublishId(), Publish.class);
            publishList.add(publish);
        }

        //3. 封装分页结果
        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        return new PageResult<Publish>((int) count, pagesize, pages, page, publishList);
    }

    @Override
    public String save(Publish publish) {
        //1. 把动态保存到publish表中
        publish.setPid(idGenerator.nextId("publish"));
        publish.setCreated(System.currentTimeMillis());
        publish.setId(ObjectId.get());
        mongoTemplate.insert(publish);


        Album album = new Album();
        album.setId(ObjectId.get());
        album.setCreated(System.currentTimeMillis());
        album.setPublishId(publish.getId());
        mongoTemplate.insert(album, "quanzi_album_" + publish.getUserId());

        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(publish.getUserId()));
        List<Friend> friends = mongoTemplate.find(query, Friend.class);
        for (Friend friend : friends) {
            TimeLine timeLine = new TimeLine();
            timeLine.setCreated(System.currentTimeMillis());
            timeLine.setId(ObjectId.get());
            timeLine.setPublishId(publish.getId());
            timeLine.setUserId(publish.getUserId());
            mongoTemplate.insert(timeLine, "quanzi_time_line_" + friend.getFriendId());
        }
        return publish.getId().toHexString();

    }

    @Override
    public PageResult findFriendMovementList(Long userId, int page, int pagesize) {
        Query query = new Query();
        query.with(Sort.by(Sort.Order.desc("created")));
        query.with(PageRequest.of(page - 1, pagesize));
        List<TimeLine> timeLines = mongoTemplate.find(query, TimeLine.class, "quanzi_time_line_" + userId);
        long count = mongoTemplate.count(query, TimeLine.class, "quanzi_time_line_" + userId);
        List<Publish> publishList = new ArrayList<>();
        for (TimeLine timeLine : timeLines) {
            Publish publish = mongoTemplate.findById(timeLine.getPublishId(), Publish.class);
            publishList.add(publish);
        }
        int pages = (int) Math.ceil(count * 1.0 / pagesize);

        return new PageResult<Publish>((int) count, pages, pages, page, publishList);
    }

    @Override
    public PageResult findAll(Long userId, int page, int pagesize) {
        Query query = new Query();

        query.with(PageRequest.of(page - 1, pagesize));
        query.with(Sort.by(Sort.Order.desc("created")));
        List<Album> albums = mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);
        long count = mongoTemplate.count(query, Album.class, "quanzi_album_" + userId);
        List<Publish> publishList = new ArrayList<>(albums.size());
        for (Album album : albums) {
            Publish publish = mongoTemplate.findById(album.getPublishId(), Publish.class);
            publishList.add(publish);
        }
        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        return new PageResult((int) count,pagesize,pages,page,publishList);
    }

    @Override
    public Publish findById(String publishId) {
        return mongoTemplate.findById(new ObjectId(publishId),Publish.class);
    }

    @Override
    public PageResult<Publish> findPublishList(int page, int pagesize, Long uid, Long state) {
        Query query = new Query().with(Sort.by(Sort.Order.desc("created"))).with(PageRequest.of(page - 1, pagesize));
        if (uid != null) {
            query.addCriteria(Criteria.where("userId").is(uid));
        }
        if (state != null) {
            query.addCriteria(Criteria.where("state").is(state));
        }
        List<Publish> publishList = mongoTemplate.find(query, Publish.class);
        long count = mongoTemplate.count(query, Publish.class);

        int pages = (int) Math.ceil(count * 1.0 / pagesize);

        return new PageResult<>((int) count, pagesize, pages, page, publishList);
    }

    @Override
    public void updateState(Publish publish) {
        Query query = new Query(Criteria.where("id").is(publish.getId()));
        Update update = new Update().set("state", publish.getState());
        mongoTemplate.updateFirst(query, update, Publish.class);


    }

    @Override
    public List<Publish> findPublishListByPids(List<Long> pids) {
        Query query = new Query();
        query.addCriteria(Criteria.where("pid").in(pids));
        return mongoTemplate.find(query, Publish.class);
    }

    @Override
    public void reject(String[] pids) {
        for (String pid : pids) {
            Query query = new Query(Criteria.where("_id").is(pid));
            Update update = new Update();
            update.set("state", 2);
            mongoTemplate.updateFirst(query, update, Publish.class);
        }
    }

    @Override
    public void pass(String[] pids) {
        for (String pid : pids) {
            Query query = new Query(Criteria.where("_id").is(pid));
            Update update = new Update();
            update.set("state", 1);
            mongoTemplate.updateFirst(query, update, Publish.class);
        }
    }
}
